package com.autumn.annotations.run;

import com.autumn.annotations.bean.config.FactoryBeanDemoConfig;
import com.autumn.annotations.bean.config.ImportDemoConfig;
import com.autumn.xa.common.util.FrameworkUtils;
import com.autumn.annotations.bean.config.BaseConfig;
import com.autumn.annotations.bean.config.ConditionalDemoConfig;
import com.autumn.annotations.bean.config.ScopeDemoConfig;
import com.autumn.annotations.demos.Config;
import com.autumn.annotations.demos.Person;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import java.util.Map;

/**
 * ClassName: DemoRun
 *
 * @Description:
 * @Author: wangqiuyang
 * @Date: 2021/12/28 下午4:18
 * History:
 * <author>          <time>          <version>          <desc>
 * wangqiuyang    2021/12/28 下午4:18   @Version 1.0        描述
 */
public class BeanRun {

    /**
    * Description: 例子
    * @param
    * @return: void
    * @author: wangqiuyang
    * @Date: 2021/12/28 下午4:26
    */
    @Test
    public void demoRun() {
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(Config.class);

        // 通过类型获取bean
        Person bean = applicationContext.getBean(Person.class);
        System.out.println(bean);

        // 通过类型u哦获取name
        String[] names = applicationContext.getBeanNamesForType(Person.class);
        for (String name : names) {
            System.out.println(name);
        }

        String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
        for (String name : beanDefinitionNames) {
            System.out.println(name);
        }


        System.out.println(applicationContext.getApplicationName());
    }

    /**
    * Description: componentScan使用
    * @author: wangqiuyang
    * @Date: 2021/12/28 下午4:29
    */
    @Test
    public void componentScanDemo() {
        AnnotationConfigApplicationContext context1 = new AnnotationConfigApplicationContext(BaseConfig.class);
        String[] names = context1.getBeanDefinitionNames();
        for (String name : names) {
            System.out.println(name);
        }
    }

    /**
    * Description: @scope
    * @author: wangqiuyang
    * @Date: 2021/12/28 下午4:29
    */
    @Test
    public void scopeDemo() {
        AnnotationConfigApplicationContext contxt = new AnnotationConfigApplicationContext(ScopeDemoConfig.class);

        System.out.println("ioc 初始化完成 ......");

        Object bean1 = contxt.getBean("person1");
        Object bean2 = contxt.getBean("person1");
        System.out.println(bean1 == bean2);
        // springframework 装填的bean 默认是单实例的
        // 使用@Scope注解可以改变是否为单实例

        Object bean3 = contxt.getBean("person2");
        Object bean4 = contxt.getBean("person2");
        System.out.println(bean3 == bean4);
        // scope 设置为 prototype 为多实例

        /*
            tips：
            单例模式的时候 会在spring初始化的时候创建实例
            多实例模式的时候 会在调用他的时候创建实例
         */


        // 单例懒加载 使用@Lazy 注解 会在第一次调用他的时候创建对象
        Object bean5 = contxt.getBean("person3");
        Object bean6 = contxt.getBean("person3");
        System.out.println(bean5 == bean6);
    }

    /**
     * Description: @conditional
     *
     * -Dos.name=linux
     * -Dos.name=windows 10
     *
     * @author: wangqiuyang
     * @Date: 2021/12/28 下午4:29
     */
    @Test
    public void conditionalDemo () {
        AnnotationConfigApplicationContext contxt = new AnnotationConfigApplicationContext(ConditionalDemoConfig.class);
        System.out.println("ioc 初始化完成 ......");

        // 获取当前系统的名称
        String osName = FrameworkUtils.getOsName(contxt);
        System.out.println("当前系统环境名称为： --> " + osName);

        // 输出所有的bean名字
        String[] names = contxt.getBeanNamesForType(Person.class);
        for (String name : names) {
            System.out.println(name);
        }

        // 输出所有的bean 用map
        Map<String, Person> beanMap = contxt.getBeansOfType(Person.class);
        System.out.println(beanMap);

    }

    /**
    * Description: 方法描述
    * @param
    * @return: void
    * @author: wangqiuyang
    * @Date: 2022/1/25 11:14 上午
    */
    @Test
    public void importDemo () {
        AnnotationConfigApplicationContext contxt = new AnnotationConfigApplicationContext(ImportDemoConfig.class);
        System.out.println("ioc 初始化完成 ......");

        // 输出所有的bean名字
        FrameworkUtils.printAllBeanNames(contxt);


    }

    /**
     * Description: 方法描述
     * @param
     * @return: void
     * @author: wangqiuyang
     * @Date: 2022/1/25 11:14 上午
     */
    @Test
    public void factoryBeanDemo () {
        AnnotationConfigApplicationContext contxt = new AnnotationConfigApplicationContext(FactoryBeanDemoConfig.class);
        System.out.println("ioc 初始化完成 ......");

        // 输出所有的bean名字
        FrameworkUtils.printAllBeanNames(contxt);

        Object bean1 = contxt.getBean("colorFactoryBean");
        Object bean2 = contxt.getBean("colorFactoryBean");
        System.out.println(bean1);
        System.out.println(bean2);
        System.out.println(bean1 == bean2);

        // 如果ColorFactoryBean.isSingleton 返回false 则上面的等式返回false
        // 因为该实例不是单例 每次getBean 都会生成一个新的bean

        Object bean3 = contxt.getBean("&colorFactoryBean");
        System.out.println(bean3.getClass());
    }

}
